package com.cicadasmall.builder.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.cicadasmall.builder.BuilderAppLauncher;
import com.cicadasmall.builder.core.GeneratorBuilder;
import com.cicadasmall.builder.dao.CodegenDao;
import com.cicadasmall.builder.vo.TableInfoVo;
import com.cicadasmall.builder.vo.TableVo;
import com.cicadasmall.builder.view.SettingView;
import de.felixroske.jfxsupport.FXMLController;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.DirectoryChooser;
import javafx.stage.Modality;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.sql.DataSource;
import java.io.File;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * JavaFx  首页控制器
 *
 * @author Jin
 */
@FXMLController
public class IndexController extends BaseController {

    @Value("${default.gen.path}")
    private String defaultGenPath;

    @Autowired
    private CodegenDao codegenDao;

    @Autowired
    private DataSource dataSource;

    @FXML
    private TextField searchTextInput;

    @FXML
    private TextField tableName;

    @FXML
    private TextField packageName;

    @FXML
    private TextField moduleName;

    @FXML
    private TextField doOutputDir;

    @FXML
    private TextField daoOutputDir;

    @FXML
    private TextField logicOutputDir;

    @FXML
    private TextField author;

    @FXML
    private Label moreBtn;

    @FXML
    private Label orderBtn;

    @FXML
    private Label refreshBtn;

    @FXML
    private Label message;

    @FXML
    private Button doGenBth;

    @FXML
    private Button doChangeDirBtn;
    @FXML
    private Button daoChangeDirBtn;

    @FXML
    private Button logicChangeDirBtn;

    @FXML
    private TableView tableListView;

    @FXML
    private TableColumn<Object, Object> tableIcon;

    @FXML
    private TableColumn<Object, Object> tableComment;

    @FXML
    private TableColumn createTime;

    @FXML
    private CheckBox removePrefix;

    @FXML
    private CheckBox restController;

    @FXML
    private CheckBox enableBaseResultMap;

    @FXML
    private CheckBox enableBaseColumnList;

    @FXML
    private CheckBox entityLombokModel;

    @FXML
    private CheckBox overrideFile;

    @FXML
    private CheckBox openOutPutDir;

    @FXML
    private ChoiceBox<DateType> dateType;

    @Override
    public void initialize() {
        settingMenuInit();
        orderMenuInit();
        searchTextInputInit();
        tableListViewInit();
        refreshMsgInit();
        changeDirBtnInit();
        doGenBthInit();
        otherInit();
    }

    private void otherInit() {
        tableName.setDisable(true);
        logicOutputDir.setText(System.getProperty("user.dir") + defaultGenPath.replace("/", File.separator));
        doOutputDir.setText(System.getProperty("user.dir") + defaultGenPath.replace("/", File.separator));
        dateType.setItems(FXCollections.observableList(Arrays.asList(DateType.values())));
        dateType.setValue(DateType.TIME_PACK);
        enableBaseColumnList.setSelected(true);
        enableBaseResultMap.setSelected(true);
        restController.setSelected(true);
        removePrefix.setSelected(true);
        openOutPutDir.setSelected(false);
        entityLombokModel.setSelected(false);
    }

    private void changeDirBtnInit() {
        //选择按钮
        directoryChooser(doChangeDirBtn, doOutputDir);
        directoryChooser(daoChangeDirBtn, daoOutputDir);
        //选择按钮
        directoryChooser(logicChangeDirBtn, logicOutputDir);
    }

    private void directoryChooser(Button btn, TextField textField) {
        btn.setOnAction(event -> {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            try {
                directoryChooser.setInitialDirectory(new File(textField.getText().replace("/", File.separator)));
                File selectedFile = directoryChooser.showDialog(BuilderAppLauncher.getStage());
                if (selectedFile == null) return;
                textField.setText(selectedFile.getAbsolutePath());
            } catch (Exception e) {
                directoryChooser.setInitialDirectory(new File(System.getProperty("user.dir").replace("/", File.separator)));
                File selectedFile = directoryChooser.showDialog(BuilderAppLauncher.getStage());
                if (selectedFile == null) return;
                textField.setText(selectedFile.getAbsolutePath());
            }
        });
    }

    private void doGenBthInit() {
        //生成按钮
        doGenBth.setOnAction(event -> {
            if (StrUtil.isEmpty(tableName.getText())) {
                showAlert("请选择需要生成的表");
            } else {
                String tablePrefix = null;
                //此处可以截取多个前缀
                if (removePrefix.isSelected()) {
                    String[] tableNameSplitArray = tableName.getText().split("_");
                    if (tableNameSplitArray.length > 1) {
                        tablePrefix = tableNameSplitArray[0];
                    }
                }
                //生成代码
                GeneratorBuilder generatorBuilder = GeneratorBuilder
                        .build()
                        .dataSourceConfig(dataSource)
                        .injectionConfig()
                        .packageConfig(packageName.getText(), moduleName.getText())
                        .strategyConfig(tablePrefix, tableName.getText(), entityLombokModel.isSelected(), restController.isSelected())
                        .globalConfig(doOutputDir.getText(), daoOutputDir.getText(), logicOutputDir.getText(), openOutPutDir.isSelected(), false, enableBaseResultMap.isSelected(), enableBaseColumnList.isSelected(), overrideFile.isSelected(), dateType.getValue(), author.getText())
                        .setCallBack(() -> showAlert("代码生成完毕！"));
                generatorBuilder.execute();
            }
        });

    }

    private void tableListViewInit() {
        //设置单元格属性
        tableIcon.setCellValueFactory(new PropertyValueFactory<>("imageView"));
        tableComment.setCellValueFactory(new PropertyValueFactory<>("tableComment"));
        createTime.setCellValueFactory(new PropertyValueFactory<>("createTime"));
        //设置表格数据
        tableListView.setItems(FXCollections.observableList(codegenDao.findTableList(null).stream().map(TableVo::toTableInfoModel).collect(Collectors.toList())));
        tableListView.setTooltip(new Tooltip("双击生成"));
        //设置鼠标点击事件（双击）
        tableListView.setOnMouseClicked(event -> {
            if (event.getClickCount() == 1) {
                TableInfoVo bean = (TableInfoVo) tableListView.getSelectionModel().getSelectedItem();
                if (null != bean) {
                    tableName.setText(bean.getTableName());
                    author.setText("Jin");
                }
            }
        });
    }

    private void refreshMsgInit() {
        refreshBtn.setOnMouseClicked(event -> {
            message.setText(ws[new SecureRandom().nextInt(7)]);
            tableListView.setItems(FXCollections.observableList(codegenDao.findTableList(null).stream().map(TableVo::toTableInfoModel).collect(Collectors.toList())));
        });
    }

    private void searchTextInputInit() {
        searchTextInput.setText("请输入表名！");
        searchTextInput.setOnMouseMoved(event -> searchTextInput.setText(""));
        searchTextInput.setOnMouseExited(event -> searchTextInput.setText("请输入表名！"));
        searchTextInput.setOnKeyReleased(event -> {
            String text = searchTextInput.getText();
            tableListView.setItems(FXCollections.observableList(codegenDao.findTableList(text).stream().map(TableVo::toTableInfoModel).collect(Collectors.toList())));
        });
    }

    private void orderMenuInit() {
        ContextMenu contextMenu = new ContextMenu();
        MenuItem up = new MenuItem("按日期升序");
        ImageView upFileImg = new ImageView("/icons/public/IconSortArrowUp.png");
        MenuItem down = new MenuItem("按日期降序");
        ImageView downFileImg = new ImageView("/icons/public/IconSortArrowDown.png");
        down.setGraphic(downFileImg);
        //升序
        up.setOnAction((ActionEvent e) -> {
            up.setGraphic(upFileImg);
            down.setGraphic(null);
            tableListView.getSortOrder().clear();
            createTime.setSortType(TableColumn.SortType.ASCENDING);
            tableListView.getSortOrder().add(createTime);

        });
        //降序
        down.setOnAction((ActionEvent e) -> {
            down.setGraphic(downFileImg);
            up.setGraphic(null);
            tableListView.getSortOrder().clear();
            createTime.setSortType(TableColumn.SortType.DESCENDING);
            tableListView.getSortOrder().add(createTime);
        });
        //右键菜单
        contextMenu.getItems().addAll(up, down);
        orderBtn.setContextMenu(contextMenu);
        orderBtn.setTooltip(new Tooltip("列表排序"));
        orderBtn.setOnMouseClicked(event -> orderBtn.getContextMenu().show(orderBtn, event.getScreenX(), event.getScreenY()));
    }

    private void settingMenuInit() {
        ContextMenu contextMenu = new ContextMenu();
        MenuItem setting = new MenuItem("设置");
        setting.setOnAction(event -> BuilderAppLauncher.showView(SettingView.class, Modality.APPLICATION_MODAL));
        MenuItem about = new MenuItem("关于");
        about.setOnAction(event -> showAlert(DateUtil.now(), Alert.AlertType.INFORMATION));
        contextMenu.getItems().addAll(setting, about);
        moreBtn.setContextMenu(contextMenu);
        moreBtn.setTooltip(new Tooltip("更多>>"));
        moreBtn.setOnMouseClicked(event -> moreBtn.getContextMenu().show(moreBtn, event.getScreenX(), event.getScreenY()));
    }
}
